package cn.openea.perpartner.meily.constant.enums;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.similarity.JaccardSimilarity;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ysk
 * @version 1.0.1
 * @Description 快递公司常量
 * @createTime 2023年05月10日 10:24:00
 */
@Getter
public enum ExpressCompany {
    YUANTONG("yuantong", "圆通速递", false),
    YUNDA("yunda", "韵达快递", false),
    SHENTONG("shentong", "申通快递", false),
    ZHONGTONG("zhongtong", "中通快递", false),
    JTEXPRESS("jtexpress", "极兔速递", false),
    YOUZHENGGUONEI("youzhengguonei", "邮政快递包裹", false),
    EMS("ems", "EMS", false),
    YOUZHENGBK("youzhengbk", "邮政标准快递", false),
    SHUNFENG("shunfeng", "顺丰速运", true),
    SHUNFENGKUAIYUN("shunfengkuaiyun", "顺丰快运", true),
    ZHONGTONGKUAIYUN("zhongtongkuaiyun", "中通快运", false),
    JD("jd", "京东物流", false),
    JINGDONGKUAIYUN("jingdongkuaiyun", "京东快运", false),

    ;

    /**
     * 快递公司编码 参考快递100官方提供的文件
     */
    private String code;

    /**
     * 快递公司名称
     */
    private String name;
    /**
     * 手机号是不是必填
     */
    private boolean requiredPhone;

    ExpressCompany(String code, String name, boolean requiredPhone) {
        this.code = code;
        this.name = name;
        this.requiredPhone = requiredPhone;
    }

    public static ExpressCompany getByCode(String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        for (ExpressCompany value : values()) {
            if (code.equals(value.getCode())) {
                return value;
            }
        }
        return null;
    }

    public static ExpressCompany getByName(String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }
        for (ExpressCompany value : values()) {
            if (name.equals(value.getName())) {
                return value;
            }
        }
        return null;
    }

    /**
     * 根据字符串匹配最相似的元素
     * 采用Jaccard相似度 算法比较
     */
    public static ExpressCompany findMostSimilarElement(String targetString) {
        double maxSimilarity = 0.0;
        String mostSimilarElement = "";
        List<String> stringArray = Arrays.stream(values()).map(ExpressCompany::getName).collect(Collectors.toList());
        JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();
        for (String element : stringArray) {
            double similarity = jaccardSimilarity.apply(element, targetString);
            if (similarity > maxSimilarity) {
                maxSimilarity = similarity;
                mostSimilarElement = element;
            }
        }
        return getByName(mostSimilarElement);
    }
}
